home *** CD-ROM | disk | FTP | other *** search
/ Apple II Magazines (DO) / Nibble Volume 12, No. 05 (1991-05)(MindCraft Publishing)(Side B).zip / Nibble Volume 12, No. 05 (1991-05)(MindCraft Publishing)(Side B).do / PROFINDER.S1.txt < prev    next >
Text File  |  1996-12-24  |  24KB  |  864 lines

  1. *********************************************
  2. *               PROFINDER.S1                *
  3. *       ProFinder source code, Part 1       *
  4. *             by Paul L. Esser              *
  5. *   (C) 1991 BY MindCraft Publ. Corp.       *
  6. *           Lincoln, Mass. 01773            *
  7. *          ProDOS Editor/Assembler          *
  8. *********************************************
  9.  MACLIB  ;Enable macros
  10.  MSB OFF ;All ASCII has high bit off
  11. * ------------------
  12. *   EQUATES
  13. * Monitor
  14. PRBL2 EQU $F94A ;Print X spaces
  15. TABV EQU $FB5B ;Vtab to A
  16. BASCALC EQU $FBC1 ;Calculate BASL
  17. VTAB EQU $FC22 ;Vtab to CV ($25)
  18. CLEOP EQU $FC42 ;Clear to end of page
  19. HOME EQU $FC58 ;Home
  20. CLEOL EQU $FC9C ;Clear to end of line
  21. RDKEY EQU $FD0C ;Read keybd
  22. GETLN EQU $FD6A ;Input line
  23. CROUT EQU $FD8E ;Output CR
  24. PRBYTE EQU $FDDA ;Print hex byte
  25. COUT EQU $FDED ;Output char.
  26. MOVE EQU $FE2C ;Move memory block
  27. BELL EQU $FF3A ;Ring bell
  28. CH EQU $24 ;Screen cursor horiz. pos.
  29. BASL EQU $28 ;Screen base address
  30. KBD EQU $C000 ;Keyboard data
  31. STROBE EQU $C010 ;Clear keybd strobe
  32. *
  33. * ProDOS Global Page
  34. DEVCNT EQU $BF31 ; # disk drives
  35. DEVLST EQU $BF32 ;list of disk drives
  36. BITMAP EQU $BF58 ;map of protected memory pages
  37. LEVEL EQU $BF94 ;open file level
  38. MACHID EQU $BF98 ;machine ID byte
  39. PFXPTR EQU $BF9A ; 0: no prefix;  >0: prefix set
  40. *
  41. * ASCII codes
  42. LARROW EQU $08 ;left arrow
  43. DARROW EQU $0A ;down  "
  44. UARROW EQU $0B ;up    "
  45. CR EQU $0D ;return 
  46. RARROW EQU $15 ;right arrow
  47. ESC EQU $1B ;escape
  48. SPACE EQU $20 ;space
  49. DEL EQU $7F ;delete key
  50. *
  51. * Memory Use
  52. IOBUFFER EQU $0800 ;I/O buffer for open files
  53. DIRSTACK EQU $0E00 ;stack of menu choice numbers
  54. T.NAMELEN EQU $0F00 ;table of name lengths of file entries
  55. DIRLOAD EQU $6000 ;location to read dir file
  56. MAXDIRSIZ EQU $9800-DIRLOAD ;max length to read dir file
  57. ENTLEN EQU DIRLOAD+$23 ;length of each dir entry
  58. ENTPERBLK EQU DIRLOAD+$24 ; # entries per dir block
  59. FILECOUNT EQU DIRLOAD+$25 ; # files in directory
  60. PN2 EQU $280 ;Secondary pathname  (Must be at $280)
  61. PN2L EQU PN2 ;length byte of PN2
  62. PN2S EQU PN2+1 ;PN2 string 
  63. PNB EQU $C80 ;Pathname of loaded BASIC.SYSTEM file
  64. PND EQU $D80 ;Pathname of current directory
  65. STARTUP EQU $2006 ;Pathname of BASIC.SYSTEM's Startup file
  66. *
  67. * Page Zero Use
  68.  DSECT
  69.  ORG $5A
  70. NUMBER DS 5 ;Decimal no. in ASCII
  71. TEMP DS 1 ;Temporary storage
  72. ENTPTR DS 2 ;Pointer to file entries in directory
  73. MENUPTR DS 2 ;Pointer to entries in menu
  74. MEMLO DS 2 ;Lowest location avail. for copying file
  75. MEMHI DS 2 ;Highest  "         "
  76. ACTIVEENT DS 1 ; # active entries in menu
  77. BLKENT DS 1 ;counter of file entries in dir block
  78. F.BASIC DS 1 ;flag  >=$80: BASIC.SYSTEM loaded
  79. F.EOF DS 1 ;flag  >=$80: EOF reached while copying
  80. F.SWAP DS 1 ;flag  >=$80: user swapping disks in copy
  81. STARTPOS DS 1 ;starting cursor pos (w/in PN1) in INPUTPN
  82. ENDPOS DS 1 ;ending    "      "
  83. CHRPTR DS 2 ;pointer to char in PRINT routine
  84. TOPENT DS 1 ;menu entry no. displayed highest on scrn
  85. MENUNUM DS 1 ;current menu entry no.
  86. CHOICE DS 1 ;user's current entry choice in MENU
  87. DIRLEVEL DS 1 ;directory level,   0: in Volume Com-
  88. ;              mands Menu,  1: in root directory,  >=2: in subdirectory
  89. CMDLIST DS 2 ;list of acceptable cmds in MENU
  90. NUMCMDS DS 1 ; # of acceptable cmds
  91. VAL DS 2 ;value used in DEC routine
  92. AUX DS 1 ;auxillary value
  93. GOTO DS 2 ;indirect JMP pointer
  94.  ORG $80
  95. PN1 EQU * ;Primary pathname (must be at $80)
  96. PN1L DS 1 ;Length byte of PN1
  97. PN1S DS 64 ;PN1 string buffer
  98.  DS 1
  99. STARTMARK DS 3 ;Mark in source file where reading began
  100. ENDMARK DS 3 ;   "      "    where last read ended
  101. P.MARK DS 1 ;GET_MARK and SET_MARK parameter table
  102. MARKRNUM DS 1 ; reference no.
  103. MARK DS 3 ; MARK position in file
  104. P.EOF DS 1 ;GET_EOF and SET_EOF parm table
  105. EOFRNUM DS 1 ; ref no.
  106. EOF DS 3 ; EOF position
  107. P.CLOSE DS 1 ;CLOSE parm table
  108. CLOSERNUM DS 1 ; ref no
  109. P.RW DS 1 ;READ and WRITE parm table
  110. RWRNUM DS 1 ; ref no
  111. RWDATA DS 2 ; location to start read/write
  112. RWCOUNT DS 2 ; # of bytes to read/write
  113. RWTRANS DS 2 ; # of bytes actually read/written
  114. P.INFO DS 1 ;GET_FILE_INFO and SET_FILE_INFO parm tbl
  115. INFOPN DS 2 ; pathname, set to PN1
  116. INFOACC DS 1 ; access code
  117. INFOTYP DS 1 ; file type
  118. INFOAUX DS 2 ; auxillary type
  119. INFOSTO DS 1 ; storage type
  120. INFOBLKS DS 2 ; # blocks used
  121.  DS 4 ; modified date,time
  122. INFOCDAT DS 4 ; created date,time
  123. P.INFO2 DS 1 ;Second GET_FILE_INFO parm table
  124. INFO2PN DS 2 ; pathname
  125.  DS 1 ; access code
  126. INFO2TYP DS 1 ; file type
  127.  DS 13 ; rest of parm table
  128.  DEND
  129. * ---------------------
  130. *  INITIALIZATION
  131. * ---------------------
  132.  ORG $1000
  133. *
  134.  CLD
  135.  LDA $C082 ;activate monitor ROM
  136.  LDX #$FF
  137.  TXS  ;initialize stack
  138.  LDA #$00
  139.  STA $3F2 ;set RESET vector to $1000
  140.  LDA #$10
  141.  STA $3F3
  142.  EOR #$A5
  143.  STA $3F4
  144.  LDX #1 ;initialize parm tables in page zero
  145.  STX P.CLOSE
  146.  INX
  147.  STX P.EOF
  148.  STX P.MARK
  149.  LDX #4
  150.  STX P.RW
  151.  LDA #>PN1
  152.  STA INFOPN
  153.  LDA #<PN1
  154.  STA INFOPN+1
  155.  STA $C00C ;turn off 80 column display
  156.  STA $C00E
  157.  STA $C000
  158.  JSR $FE93 ;PR#0
  159.  JSR $FE89 ;IN#0
  160.  JSR $FE84 ;NORMAL
  161.  JSR $FB2F ;TEXT
  162.  JSR CLOSEALL ;close all files
  163.  LDA #0
  164.  LDX #$17
  165. INIT1 STA BITMAP,X ;initialize bitmap
  166.  DEX  ;(free all pages except 0,1,4,5,6,7,$BF)
  167.  BNE INIT1
  168.  INC BITMAP+$17
  169.  LDA #$CF
  170.  STA BITMAP
  171.  LDA #$EF ;Check chkpoints in program which should
  172.  CMP CHKPOINT1 ;have $EF bytes.  If the $EF byte
  173.  BNE FALLOUT ;isn't there, then part of program must
  174.  CMP CHKPOINT2 ;have been erased, so go to FALLOUT
  175.  BNE FALLOUT ;routine.
  176.  JMP START ;If OK, execute program as normal.
  177. *
  178. FALLOUT JSR HOME ;FALLOUT: loads an application program
  179.  PRINT M.FALLOUT
  180.  LDA #0
  181.  STA PN2L
  182.  MLI $C6,P.PREFIX,  ;SET_PREFIX to a null prefix
  183.  LDA #$BF ;Use "?" character as prompt
  184.  STA $33
  185. FT1 JSR GETLN ;Get pathname from user
  186.  JSR CROUT
  187.  STX PN1L
  188.  DEX
  189.  CPX #$40 ;If nothing input or pathname >64 chars,
  190.  BCS FT1 ;then try again
  191. FT2 LDA $200,X
  192.  STA PN1S,X ;Move pathname from input buffer to PN1
  193.  DEX
  194.  BPL FT2
  195.  JSR READSYS ;Read in system file
  196.  BCC RUNSYS ;If no error, run it.
  197.  JSR PRERR ;If error, print err message and try again
  198.  JMP FT1
  199. M.FALLOUT ASC 'Enter full pathname of application'
  200.  DFB CR,CR+128
  201. *
  202. * Run a system program loaded at $2000
  203. RUNSYS JSR MOVPN12 ;Move system pathname to $280 (required)
  204.  JSR HOME ;Clear screen
  205.  STA STROBE ;and keyboard
  206.  JMP $2000 ;Execute system program
  207. *
  208. * MOVPN routines:  Move pathnames to or from PN1
  209. MOVPN12 LDX #<PN2 ;move PN1 to PN2
  210. MOVPN1X TXA  ;move PN1 to PN(X-reg)
  211.  LDX #<PN1
  212.  JMP MOVPN
  213. MOVPN21 LDX #<PN2 ;move PN2 to PN1
  214. MOVPNX1 LDA #<PN1 ;move PN(X-reg) to PN1
  215. MOVPN STA $43
  216.  STX $3D ;set up for monitor MOVE routine
  217.  STX $3F
  218.  LDA #$80 ;Note:  These routines assume
  219.  STA $3C ;that all pathnames are stored
  220.  STA $42 ;at $xx80
  221.  LDA #$C0
  222.  STA $3E
  223.  LDY #0
  224.  JMP MOVE
  225. *
  226. * DOPRINT:  Print string (call with pointer in A low, Y high).
  227. *    Printing stops at byte with high bit on (negative ASCII).
  228. *    DCI directive creates string with last byte only having high bit on
  229. DOPRINT STA CHRPTR ;set up pointer
  230.  STY CHRPTR+1
  231. PRINT1 LDY #0
  232.  LDA (CHRPTR),Y ;get char
  233.  BMI PRINTA ;if high bit on, it is last char to print
  234.  JSR PRINTA ;otherwise print it and get another
  235.  JMP PRINT1
  236. PRINTA ORA #$80
  237.  BIT MACHID ;if running on a II Plus
  238.  BMI PRINTA1 ;then convert lowercase to upper
  239.  CMP #$E0
  240.  BCC PRINTA1
  241.  AND #$DF
  242. PRINTA1 JSR COUT ;output char
  243.  INC CHRPTR ;increment pointer
  244.  BNE RTS6
  245.  INC CHRPTR+1
  246. RTS6 RTS
  247. *
  248. * Print error message.  Call with error code in A.
  249. PRERR LDX #NERRCODES-1
  250. PRERR1 CMP ERRCODES,X ;Compare with list of known error codes
  251.  BEQ PRERR2
  252.  DEX
  253.  BPL PRERR1
  254.  PHA  ;If unknown error code,
  255.  PRINT E27, ;then print "I/O ERROR $xx"
  256.  JSR PRINT1
  257.  PLA
  258.  JSR PRBYTE
  259.  JMP PRERR4
  260. PRERR2 LDY #<ERRMSG ;If known error code,
  261.  LDA ERRTABLE,X ;print error message in table
  262.  CMP #>ERRMSG
  263.  BCS PRERR3
  264.  INY
  265. PRERR3 JSR DOPRINT
  266. PRERR4 JSR BELL ;ring bell
  267. CROUT2 JSR CROUT ;output 2 CR's
  268.  JMP CROUT ;Note:  CROUT2 is called independently
  269. *
  270. ERRCODES DFB $27,$28,$2B,$40,$44,$45,$46,$47,$48,$49,$4B,$4E,$52
  271.  DFB $80,$81,$82,$83,$84
  272. NERRCODES EQU *-ERRCODES
  273. ERRTABLE DFB E27,E28,E2B,E40,E44,E45,E46,E47,E48,E49,E4B,E4E,E52
  274.  DFB E80,E81,E82,E83,E84
  275. ERRMSG EQU *
  276. E27 DCI 'I/O ERROR'      ;The following are MLI errors 
  277.  DCI '  $'
  278. E28 DCI 'NO DEVICE CONNECTED'
  279. E2B DCI 'WRITE PROTECTED'
  280. E40 DCI 'BAD PATHNAME'
  281. E44 EQU *
  282. E45 EQU *
  283. E46 DCI 'PATH NOT FOUND'
  284. E47 DCI 'DUPLICATE FILE NAME'
  285. E48 DCI 'DISK FULL'
  286. E49 DCI 'DIRECTORY FULL'
  287. E4B DCI 'FILE TYPE MISMATCH'
  288. E4E DCI 'FILE LOCKED'
  289. E52 DCI 'NON-PRODOS DISK'
  290. E80 DCI 'BASIC.SYSTEM NOT FOUND'        ;The following are NOT
  291. E81 DCI 'BAD VERSION OF BASIC' ;MLI errors, they are
  292. E82 DCI 'NO PREFIX'           ;specific to this
  293. E83 DCI 'PREFIX NOT FOUND'        ;program
  294. E84 DCI 'FILE IS SPARSE'
  295. *
  296. * MLI Parameter tables.  (Some are here, others are in Page Zero.)
  297. P.OPEN DFB 3 ;OPEN parm table
  298. OPENPN DW PN1 ; pathname, may be changed to PN2
  299.  DW IOBUFFER ; file buffer
  300. OPENRNUM DFB 0 ; returned ref no.
  301. P.ONLINE DFB 2 ;ONLINE parm table
  302. ONLINUNIT DFB 0 ; unit no.
  303.  DW PN2S ; vol. name
  304. P.RENAME DFB 2 ;RENAME parm table
  305.  DW PN2 ; orig. pathname
  306.  DW PN1 ; new    "
  307. P.DESTROY DFB 1 ;DESTROY parm table
  308.  DW PN1 ; pathname
  309. P.PREFIX DFB 1 ;GET_PREFIX and SET_PREFIX parm table
  310.  DW PN2 ; pathname
  311. P.CREATE DFB 7 ;CREATE parm table
  312.  DW PN1 ; pathname
  313.  DFB $C3 ; access code, $C3 = unlocked
  314. CRTYP DFB 0 ; file type
  315.  DW 0 ; aux type
  316.  DFB 1 ; storage type, 1 = standard
  317. CRCDAT DW 0,0 ; created date,time
  318. P.CRDIR DFB 7 ;CREATE parm table to create subdirectory
  319.  DW PN1 ; pathname
  320.  DFB $C3 ; access
  321.  DFB $F ; file type, $F = DIR
  322.  DW 0 ; aux type
  323.  DFB $D ; storage type, $D = subdirectory
  324.  DW 0,0 ; created date,time
  325. *
  326. * Subroutines which perform MLI calls
  327. OPENPN2 LDA #<PN2 ;Open file in PN2
  328.  BNE OPEN1
  329. OPENPN1 LDA #<PN1 ;Open file in PN1
  330. OPEN1 STA OPENPN+1
  331.  MLI $C8,P.OPEN, ;OPEN
  332.  LDX OPENRNUM ;copy ref no. to other parm tables
  333.  STX RWRNUM
  334.  STX MARKRNUM
  335.  STX EOFRNUM
  336.  STX CLOSERNUM
  337.  RTS
  338. *
  339. GETINFO LDA #$A
  340.  STA P.INFO
  341.  MLI $C4,P.INFO, ;GET_FILE_INFO
  342.  LDX INFOSTO ;X = storage type
  343.  LDY INFOTYP ;Y = file type
  344.  RTS
  345. *
  346. SETINFO LDA #7
  347.  STA P.INFO
  348.  MLI $C3,P.INFO, ;SET_FILE_INFO
  349.  RTS
  350. *
  351. READ MLI $CA,P.RW, ;READ
  352.  BCC CLCRTS1
  353.  CMP #$4C ;Ignore end of file error ($4C),
  354.  BEQ CLCRTS1 ;but treat other errors as normal 
  355. SECRTS1 SEC
  356.  RTS
  357. CLCRTS1 CLC
  358.  RTS
  359. *
  360. READSYS JSR GETINFO ;Read a system file
  361.  BCS SECRTS1
  362.  LDA #$4B
  363.  CPY #$FF ;Make sure it is a SYS file, or else
  364.  BNE SECRTS1 ;report a "FILE TYPE MISMATCH" error
  365.  JSR OPENPN1 ;Open it
  366.  BCS SECRTS1
  367.  LDA #0
  368.  STA RWDATA
  369.  STA RWCOUNT
  370.  LDA #$20 ;Read it at $2000
  371.  STA RWDATA+1
  372.  LDA #$98 ;Read $9800 bytes max
  373.  STA RWCOUNT+1
  374.  JSR READ
  375. *
  376. CLOSEALL PHP  ;Close all files
  377.  PHA  ;save error code & status
  378.  LDA #0
  379.  STA LEVEL ;set file level to 0 to close ALL files
  380.  STA CLOSERNUM
  381.  MLI $CC,P.CLOSE, ;CLOSE
  382.  PLA
  383.  PLP  ;restore error code & status
  384.  RTS
  385. *
  386. * NOTE:  PROGRAM COUNTER MAY NOT EXCEED $1300 AT THIS POINT
  387. *
  388.  DS $1300-*,0 ;FILL WITH ZEROS UP TO $1300
  389. *
  390.  LDA #1 ;This bit of code will reside at $1300,
  391.  SEC  ;which maps to $D400 in bank 2 of bank-
  392.  RTS  ;switched RAM, in case someone goes there.
  393. *
  394. CHKPOINT1 DFB $EF ;Checkpoint 1 must contain $EF
  395. * ----------------
  396. *   MAIN PROGRAM
  397. * ----------------
  398. START JSR CLBASIC ;BASIC.SYSTEM not yet loaded into memory.
  399.  LDA #1
  400.  STA DIRSTACK ;Set menu selection to first disk drive.
  401.  JSR NEWDISK ;Start in Volume Commands Menu.
  402. *
  403. MAIN JSR HOME ;Set up screen display.
  404.  LDX DIRLEVEL ;If DIRLEVEL=0, then in Volume Commands
  405.  BNE MAIN1 ; Menu, otherwise in File Commands Menu.
  406.  PRINT M.BANNER
  407.  LDA #2
  408.  JSR VTABLINE ;Vtab 2, Htab 0
  409. MAIN1 PRINT M.PREFIX
  410.  MLI $C7,P.PREFIX,  ;GET_PREFIX call
  411.  BCS MAIN2
  412.  JSR MOVPN21
  413.  JSR PRPN1 ;Display the prefix
  414. MAIN2 LDX DIRLEVEL
  415.  BEQ MAIN3 ;If in File Cmds Menu, also display the
  416.  LDX #<PND ; current directory.  Note that current
  417.  JSR MOVPNX1 ; dir pathname moved from PND to PN1.
  418.  LDA #2 ; Some file commands expect it to be there
  419.  JSR VTABLINE
  420.  PRINT M.DIR
  421.  JSR PRPN1
  422. MAIN3 LDA #18
  423.  JSR VTABLINE ;Vtab 18  (on 0-23 scale)
  424.  LDX #40
  425. MAIN4 LDA #$BD ;Print "=" 40 times in line 18
  426.  JSR COUT
  427.  DEX
  428.  BNE MAIN4
  429.  LDA #4
  430.  JSR VTABLINE ;Vtab 4
  431.  LDX DIRLEVEL
  432.  BNE MAINF ;Branch if in File Commands Menu
  433. *
  434.  PRINT M.VHEADER, ;Print volume commands header
  435.  JSR HOME19
  436.  PRINT M.VCMDS, ;Print command list at bottom of screen
  437.  LDX #>VCMDLIST
  438.  LDA #<VCMDLIST
  439.  LDY #VNUMCMDS-1
  440.  JSR MENU ;Display disk drives, get volume command
  441.  LDA VGOTO,X
  442.  STA GOTO ;Put address of cmd handler in GOTO
  443.  LDA VGOTO+1,X
  444.  STA GOTO+1
  445.  JMP EXECUTE ;Execute volume command
  446. *
  447. MAINF PRINT M.FHEADER, ;Print file commands header
  448.  JSR HOME19
  449.  PRINT M.FCMDS, ;Print command list at bottom of screen
  450.  LDX #>FCMDLIST
  451.  LDA #<FCMDLIST
  452.  LDY #FNUMCMDS-1
  453.  JSR MENU ;Display files, get file command
  454.  LDA FGOTO,X
  455.  STA GOTO ;Put address of cmd handler in GOTO
  456.  LDA FGOTO+1,X
  457.  STA GOTO+1
  458.  CPY #FILSPCMDS ;If command is not a file specific
  459.  BCS EXECUTE ; command, then execute command now.
  460.  LDX ACTIVEENT ;If it is, then GET FILENAME FIRST.
  461.  BEQ MAINJ ;No files?  Do nothing then.
  462.  LDX MENUNUM ;Get user's file choice.
  463.  JSR SETPTR ;Find the menu entry.
  464.  LDA PN1L
  465.  LDX MENUNUM
  466.  CLC
  467.  ADC T.NAMELEN,X ;If pathname exceeds 64 chars, report
  468.  CMP #$41 ; a BAD PATHNAME error.
  469.  BCC MAINF1
  470.  LDA #$40
  471.  JSR ERROR
  472. MAINJ JMP MAIN
  473. MAINF1 STA PN1L ;Append filename in menu entry to the
  474.  LDY T.NAMELEN,X ; directory pathname already in PN1 to
  475.  TAX  ; make a complete pathname to the
  476. MAINF2 LDA (MENUPTR),Y ; selected file.
  477.  DEX
  478.  STA PN1S,X
  479.  DEY
  480.  BNE MAINF2
  481.  JSR MOVPN12 ;Pathname of selected file in PN1 and PN2
  482. *
  483. EXECUTE JSR EXECUTE1 ;Now execute the command
  484.  JMP MAIN
  485. EXECUTE1 JMP (GOTO)
  486. *
  487. VCMDLIST DFB CR,'O','R','A'       ;List of volume commands
  488. VNUMCMDS EQU *-VCMDLIST        ;Number of volume commands
  489. VGOTO DW CATVOL,ONLINE,RENAMEVOL,ONLINEALL      ;Command handlers
  490. FCMDLIST DFB CR,'C','R','K','D'   ;List of file specific commands
  491. FILSPCMDS EQU *-FCMDLIST        ;Number of file specific commands
  492.  DFB ESC,'B','P','L','S'  ;Non-file specific file commands
  493. FNUMCMDS EQU *-FCMDLIST        ;Total number of file commands
  494. FGOTO DW RUNCAT,COPY,RENAMEFIL,LKUNLK,DELETE    ;Command handlers
  495.  DW NEWDISK,BACKDIR,SETPFX,LOADRUNB,CREATEDIR
  496. *
  497. * MENU:  Displays menu entries and accepts a command from user.
  498. *   Input: (X=lo,A=hi) Pointer to list of ASCII commands
  499. *          Y=Number of acceptable commands minus 1
  500. *   Output: Y=Command number, range 0 to input Y
  501. *           X=twice Y
  502. *           A,MENUNUM,CHOICE = Menu choice selected with arrow keys    
  503. MCHOICES EQU 13 ;Number of entries on screen at one time
  504. MCENTER EQU 7 ;Center of screen entry
  505. CVTOP EQU 4 ;Vtab of topmost entry minus 1
  506. MENU STX CMDLIST
  507.  STA CMDLIST+1 ;Save command list pointers
  508.  STY NUMCMDS
  509. MENUC LDX ACTIVEENT
  510.  BEQ MENUK ;If no active entries, skip
  511.  LDA CHOICE
  512.  BEQ MENUC1 ;Make sure CHOICE is between
  513.  CMP ACTIVEENT ;1 and ACTIVEENT; adjust it
  514.  BCC MENUC2 ;as necessary
  515.  STX CHOICE
  516.  BCS MENUC2
  517. MENUC1 INC CHOICE
  518. MENUC2 LDA #1 ;Calculate TOPENT; the menu entry
  519.  CPX #MCHOICES+1 ;to be displayed highest in the screen
  520.  BCC MENUD ;such that the current choice
  521.  LDY CHOICE ;falls in the center of the screen,
  522.  CPY #MCENTER ;unless choice is at beginning
  523.  BCC MENUD ;or end of list.
  524.  TXA  ;(e.g. if CHOICE=10 and ACTIVEENT=20, then
  525.  SBC CHOICE ; TOPENT=4, so entries 4 to 16 are
  526.  CMP #MCHOICES-MCENTER
  527.  BCS MENUC3 ; displayed and 10 is in center of screen)
  528.  TXA
  529.  SEC
  530.  SBC #MCHOICES-1
  531.  JMP MENUD
  532. MENUC3 LDA CHOICE
  533.  SBC #MCENTER-1
  534. MENUD STA TOPENT ;TOPENT calculated
  535.  STA MENUNUM
  536. MENUD1 JSR PRENTRY ;Now print each menu entry 1 at a time
  537.  BCS MENUK ;Stop when bottom of display area
  538.  INC MENUNUM ;or end of menu entries reached
  539.  LDA ACTIVEENT
  540.  CMP MENUNUM
  541.  BCS MENUD1
  542. MENUK STA STROBE ;Get keystroke
  543. MENUK1 LDA KBD
  544.  BPL MENUK1
  545.  JSR UPCASE
  546.  CMP #LARROW ;Left or Up arrow:
  547.  BEQ MENUUP ;go up one choice
  548.  CMP #UARROW
  549.  BEQ MENUUP
  550.  CMP #RARROW ;Right or Down arrow:
  551.  BEQ MENUDOWN ;go down one
  552.  CMP #DARROW
  553.  BEQ MENUDOWN
  554.  LDY NUMCMDS ;Not an arrow key:
  555. MENUK2 CMP (CMDLIST),Y ;Compare keystroke with list of
  556.  BEQ MENUK3 ;acceptable commands
  557.  DEY
  558.  BPL MENUK2
  559.  BMI MENUK ;Not found: get another keystroke
  560. MENUK3 STY TEMP ;Found an acceptable command:
  561.  JSR HOME19 ;Clear bottom of screen and
  562.  LDY TEMP ;return result in X,Y,MENUNUM
  563.  ASL TEMP
  564.  LDX TEMP
  565.  LDA CHOICE
  566.  STA MENUNUM
  567.  RTS
  568. MENUDOWN INC CHOICE ;Go down one menu entry
  569.  BNE MENUC
  570. MENUUP DEC CHOICE ;Go up one
  571.  JMP MENUC ;(MENUC keeps CHOICE within limits)
  572. *
  573. PRENTRY LDX MENUNUM ;Print 1 entry in menu display
  574.  JSR SETPTR ;Set menu pointer to entry
  575.  LDA MENUNUM
  576.  SEC  ;Calculate where to display it
  577.  SBC TOPENT ;(relative to TOPENT at top of display)
  578.  CMP #MCHOICES
  579.  BCS PRENTRY3 ;Exit w/carry set if entry "off screen"
  580.  ADC #CVTOP+1
  581.  JSR BASCALC
  582.  LDX MENUNUM
  583.  LDY #38
  584. PRENTRY1 LDA (MENUPTR),Y ;Display using absolute screen addressing
  585.  ORA #$80
  586.  CPX CHOICE
  587.  BNE PRENTRY2
  588.  AND #$3F ;If MENUNUM = current choice, use INVERSE
  589. PRENTRY2 STA (BASL),Y
  590.  DEY
  591.  BPL PRENTRY1
  592.  CLC  ;Exit w/carry clear if entry displayed
  593. PRENTRY3 RTS
  594. *
  595. M.BANNER DCI '============== ProFinder ==============='
  596. M.FHEADER DCI '=NAME============TYPE==BLOCKS==MODIFIED='
  597. M.VHEADER DCI '=SLOT=DRIVE==VOLUME=======BLOCKS FREE==='
  598. M.FCMDS ASC '<RETURN> Run/Catalog <ESC> New Disk'
  599.  DFB CR
  600.  ASC '<C> Copy file        <B> Back Directory'
  601.  DFB CR
  602.  ASC '<R> Rename           <P> Set Prefix'
  603.  DFB CR
  604.  ASC '<K> Lock/Unlock      <L> Load BASIC'
  605.  DFB CR
  606.  DCI '<D> Delete           <S> Create Subdir'
  607. M.VCMDS ASC '<RETURN> Catalog'
  608.  DFB CR
  609.  ASC '<O> Online           <A> Online All'
  610.  DFB CR
  611.  DCI '<R> Rename'
  612. M.PREFIX DCI 'Prefix:    '
  613. M.DIR DCI 'Directory: '
  614. * ----------------------------
  615. *  VOLUME COMMAND HANDLERS
  616. * ----------------------------
  617. * GETVOL: Get volume name & volume info, then display it to screen
  618. *  Input: MENUNUM     Output: volume name in PN1
  619. GETVOL LDX MENUNUM
  620.  JSR SETPTR ;Set MENUPTR to point to menu entry
  621.  LDY #10
  622.  LDA #SPACE
  623. GETVOL1 STA (MENUPTR),Y ;Erase previous info by writing spaces
  624.  INY
  625.  CPY #39
  626.  BNE GETVOL1
  627.  JSR GETUNITNO ;Get unit no. of current entry
  628.  STA ONLINUNIT
  629.  MLI $C5,P.ONLINE,  ;ONLINE call to get volume name
  630.  BCS GETERR2
  631.  JSR MOVPN21 ;Put vol name in PN1
  632.  LDA PN1S
  633.  AND #$0F ;Get length of name
  634.  BEQ GETERR1 ;if 0, then error, err code in next byte 
  635.  TAX
  636.  INX
  637.  STX PN1L
  638.  LDA #'/' ;Put slash in front of name
  639.  STA PN1S
  640.  LDX #0
  641.  LDY #12
  642. GETVOL2 LDA PN1S,X ;Move vol name into menu entry
  643.  STA (MENUPTR),Y ;for later display (at htab 12)
  644.  INY
  645.  INX
  646.  CPX PN1L
  647.  BCC GETVOL2
  648.  JSR GETINFO ;Get vol info
  649.  BCS GETERR2
  650.  LDA INFOAUX ;Calculate #free blocks
  651.  SEC  ;free blks = AUX type (total blks) minus
  652.  SBC INFOBLKS ;            blocks used
  653.  TAX
  654.  LDA INFOAUX+1
  655.  SBC INFOBLKS+1
  656.  JSR DEC ;Convert to decimal ASCII
  657.  LDY #30
  658.  JSR PUTNUM ;Put number into menu entry (htab 30)
  659.  CLC
  660.  BCC GETVOLEND
  661. GETERR1 LDA PN1S+1
  662. GETERR2 SEC
  663. GETVOLEND PHP  ;Save error status
  664.  PHA
  665.  JSR PRENTRY ;Print to screen
  666.  JSR VTAB ;Restore previous screen cursor
  667.  PLA
  668.  PLP  ;Restore error status and exit
  669.  RTS
  670. *
  671. * GETUNITNO:  Get unit no. from DEVLST
  672. * Input: MENUNUM      Output: A = Unit no.
  673. GETUNITNO LDA ACTIVEENT ;Unit nos. stored in DEVLST
  674.  SEC  ;(in reverse order)
  675.  SBC MENUNUM
  676.  TAX
  677.  LDA DEVLST,X
  678.  AND #$F0
  679.  RTS
  680. *
  681. * ONLINEALL, RENAMEVOL, ONLINE, CATVOL:  Volume command handlers
  682. *  for  <A> Online All,  <R> Rename,  <O> Online,  <RETURN> Catalog
  683. ONLINEALL LDA #1 ;Get online vol name for each disk drive
  684.  STA MENUNUM ;For MENUNUM = 1 to ACTIVEENT do:
  685. ALL1 JSR GETVOL ;get volume
  686.  LDX MENUNUM
  687.  INC MENUNUM
  688.  CPX ACTIVEENT
  689.  BCC ALL1 ;Next MENUNUM
  690.  RTS
  691. *
  692. M.RENAME DCI 'New name: '
  693. RENAMEVOL JSR GETVOL ;Get volume to rename
  694.  BCS ERRORJ5 ;Error exit
  695.  JSR MOVPN12 ;Move vol pathname to PN2
  696.  LDX #1
  697.  STX PN1L ;Clear PN1 except for "/"
  698.  PRINT M.RENAME, ;Ask for name
  699.  LDA #$AF ;Print "/" character preceding input
  700.  JSR COUT
  701.  JSR INPUTPN ;Input name
  702.  BCS RTS8 ;Cancel rename if <ESC> pressed
  703.  JSR CROUT2
  704.  MLI $C2,P.RENAME,  ;RENAME call
  705.  BCS ERRORJ5
  706. *
  707. ONLINE JSR GETVOL ;Get online volume
  708.  BCC RTS8
  709. ERRORJ5 JMP ERROR ;Error exit
  710. *
  711. CATVOL JSR GETVOL ;Catalog volume
  712.  BCS ERRORJ5
  713. *
  714. CATALOG JSR READDIR ;Catalog a directory (Volume or Subdir)
  715.  BCS ERRORJ5
  716.  LDX DIRLEVEL ;If successful, save current menu choice
  717.  LDA CHOICE ;number in DIRSTACK so the Back Directory
  718.  STA DIRSTACK,X ;command can find its way back.
  719.  INC DIRLEVEL ;Directory level is 1 higher
  720.  LDA #1 ;Start new dir with file choice #1
  721.  STA CHOICE
  722. RTS8 RTS
  723. * -----------------------------------
  724. *   FILE "LOAD/RUN" COMMAND HANDLERS 
  725. * -----------------------------------
  726. * <L> Load Basic command
  727. LOADRUNB JSR LOADBASIC ;Load BASIC.SYSTEM if not loaded already
  728.  BCS ERRORJ2
  729.  LDA #0 ;Clear BASIC.SYSTEM's STARTUP pathname so 
  730.  STA STARTUP ;no startup program is run
  731.  PRINT M.EXITB, ;Ask if user wants to exit
  732.  JSR YN ;Get "Y" or "N"
  733.  BCC RUNSYSJ ;Run BASIC if user responds "Y"
  734. RTS9 RTS
  735. M.EXITB DCI 'Exit to BASIC'
  736. *
  737. * <RETURN> Run/Catalog command
  738. RUNCAT JSR GETINFO ;Get file info
  739.  BCS ERRORJ2
  740.  CPX #$0D ;If subdirectory (storage type = $D), then
  741.  BEQ CATALOG ;catalog it
  742.  CPY #$FF
  743.  BEQ RUN ;Make sure file type is acceptable
  744.  CPY #$FC ;Acceptable file types include SYS ($FF),
  745.  BEQ RUN ; BAS ($FC), BIN (6), and TXT (4).
  746.  CPY #$06
  747.  BEQ RUN
  748.  CPY #$04
  749.  BEQ RUN
  750.  NOP   ;These four NOP's reserve space for one
  751.  NOP   ;additional file type to be accepted.
  752.  NOP   ;Replace NOP's with      C0 nn   CPY #$nn
  753.  NOP   ;this for type $nn:      F0 05   BEQ RUN
  754. ;
  755.  LDA #$4B ;If bad type, report "TYPE MISMATCH ERROR"
  756. ERRORJ2 JMP ERROR
  757. RUN PRINT M.RUN, ;Ask if user wants to run
  758.  JSR YN ;Get "Y" or "N"
  759.  BCS RTS9 ;Exit if "N"
  760.  LDY INFOTYP ;Run program if "Y"
  761.  CPY #$FF
  762.  BNE RUN2 ;If SYS ($FF) type file, load it
  763.  JSR LOADSYS ;and execute it.
  764.  BCS ERRORJ2
  765.  BCC RUNSYSJ
  766. RUN2 JSR LOADBASIC ;If any other file type, then load
  767.  BCS ERRORJ2 ; BASIC.SYSTEM first.
  768.  LDX #$40
  769. RUN3 LDA PN2,X ;Replace BASIC.SYSTEM's STARTUP pathname
  770.  STA STARTUP,X ;with pathname of file user wants to run,
  771.  DEX  ;then execute BASIC.SYSTEM
  772.  BPL RUN3
  773. RUNSYSJ JMP RUNSYS ;Run system program
  774. M.RUN DCI 'Run this program'
  775. *
  776. * Load a system program at $2000
  777. LOADSYS JSR CLBASIC ;Clear BASIC.SYSTEM from memory if there
  778.  JSR READSYS ;Read system file
  779.  PHP
  780.  PHA  ;Save error status
  781.  LDA RWTRANS+1
  782.  CLC
  783.  ADC #$20 ;Just in case sys file is so big that
  784.  CMP MEMHI+1 ;it overruns menu entry storage, then
  785.  BCC LOAD1 ;nullify the current directory
  786.  JSR NEWDISK
  787. LOAD1 PLA
  788.  PLP  ;Restore error status
  789.  RTS
  790. *
  791. * Load BASIC.SYSTEM into memory
  792. LOADBASIC BIT F.BASIC ;If BASIC.SYSTEM already loaded
  793.  BPL LB1 ;(F.BASIC flag >= $80) then don't need
  794.  LDX #<PNB ;to load it again.  Just restore its
  795.  JSR MOVPNX1 ;pathname to PN1
  796.  CLC
  797.  RTS
  798. LB1 JSR FINDSLASH ;First set up pathname of BASIC.SYSTEM
  799.  TXA  ;file
  800.  CLC
  801.  ADC #BASICL
  802.  TAY
  803.  LDA #$40
  804.  CPY #$41 ;Just in case pathname too long (65 chrs)
  805.  BCS SECRTS2 ;report "BAD PATHNAME"
  806.  STY PN1L
  807.  LDY #0
  808. LB2 LDA BASIC,Y ;Append "BASIC.SYSTEM" file name to
  809.  STA PN1S,X ;current dir pathname already in PN1
  810.  INX
  811.  INY
  812.  CPY #BASICL
  813.  BNE LB2
  814.  JSR LOADSYS ;Load BASIC.SYSTEM
  815.  BCC LB3
  816.  CMP #$46 ;If file not found, report
  817.  BEQ NOBASIC ;"BASIC.SYSTEM NOT FOUND"
  818.  CMP #$4B ;If wrong file type, report
  819.  BNE SECRTS2 ;"BAD VERSION OF BASIC"
  820. BADBASIC LDA #$81
  821. SECRTS2 SEC  ;Other errors handle as usual
  822.  RTS
  823. NOBASIC LDA #$80
  824.  SEC
  825.  RTS
  826. LB3 LDX $2000 ;Make sure BASIC.SYSTEM adheres
  827.  CPX #$4C ;to the "auto-run protocol",
  828.  BNE BADBASIC ;or else report "BAD VERSION OF BASIC"
  829.  LDX #$EE
  830.  CPX $2003
  831.  BNE BADBASIC
  832.  CPX $2004
  833.  BNE BADBASIC
  834.  LDX $2005
  835.  CPX #$41
  836.  BCC BADBASIC
  837.  LDX RWTRANS+1
  838.  BEQ BADBASIC
  839.  CPX #<DIRLOAD-$2000  ;Make sure BASIC.SYSTEM is less than
  840.  BCS BADBASIC ;16K in size to avoid memory conflicts
  841.  LDA RWTRANS ;within program  (Normally it's 10K).
  842.  STA MEMLO ;OK: we got BASIC in memory now
  843.  LDA RWTRANS+1
  844.  ADC #$20 ;Raise MEMLO pointer above end of loaded 
  845.  STA MEMLO+1 ;BASIC file to protect it from COPY cmd
  846.  SEC
  847.  ROR F.BASIC ;Set F.BASIC flag
  848.  LDX #<PNB
  849.  JSR MOVPN1X ;Save BASIC.SYSTEM's pathname to PNB
  850.  CLC
  851.  RTS
  852. *
  853. BASIC ASC 'BASIC.SYSTEM'
  854. BASICL EQU *-BASIC
  855. *
  856. CLBASIC LSR F.BASIC ;Clear F.BASIC flag to indicate 
  857.  LDA #0 ;BASIC.SYSTEM not loaded into memory
  858.  STA MEMLO
  859.  LDA #$1F ;Set MEMLO to $1F00; lowest memory 
  860.  STA MEMLO+1 ;available for copying files
  861.  RTS
  862. *-------------------------------------------------------------------
  863.  CHN PROFINDER.S2 ;Chain to second part of source code.
  864.